import moment from 'moment';
import mongoose from 'mongoose';
import config from '../../config';

class OffDutyReply {
  async getOffDutyRobot() {
    if (this.offDutyRobot) return this.offDutyRobot;
    const User = mongoose.model('User');
    const offDutyRobot = await User.findOne({ username: '值班机器人', isRobot: true });
    this.offDutyRobot = offDutyRobot;

    return offDutyRobot;
  }

  async sendMessage(messageHandler, toChannel, message) {
    const offDutyRobot = await this.getOffDutyRobot();
    await messageHandler.post(toChannel, offDutyRobot, message);
  }

  async handle({ user, message, messageHandler }) {
    if (!OffDutyReply.isMessageFromStudent(user)) return;
    const offDutyMessage = OffDutyReply.offDutyCheck(
      new Date(),
      this.offDutyRange || config.offDutyRange,
    );

    if (!offDutyMessage) return;

    const isInService = await this.isInService(user, message.toChannel);
    if (isInService) return;

    await this.sendMessage(messageHandler, message.toChannel, {
      mention: [user.id],
      toSocialId: message.fromSocialId,
      subType: 'text',
      body: `@${user.nickname}: ${offDutyMessage}`,
    });
  }

  async isInService(user, channelId) {
    const Channel = mongoose.model('Channel');
    const channel = await Channel.findById(channelId);

    if (!channel) {
      return false;
    }

    return channel.isInService(user);
  }

  static offDutyCheck(now, rangeArray) {
    const today = moment().format('YYYY-MM-DD');

    const offDutyRange = rangeArray.map((rangeItem) => {
      const start = rangeItem.start.replace('%today%', today);
      const end = rangeItem.end.replace('%today%', today);

      return {
        message: rangeItem.message,
        inRange(date) {
          return moment(date).isBetween(start, end);
        },
      };
    });

    const matched = offDutyRange.find(range => range.inRange(now));
    return matched ? matched.message : null;
  }

  static isMessageFromStudent(user) {
    return user.group.name === '学生';
  }
}

const offDutyReply = new OffDutyReply();

export { OffDutyReply };
export default offDutyReply;
